from typing import Optional, List

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select

from app.db.SoftCopyrightDB import SoftCopyrightDB, utc_now
from app.dto.GaiDto import SoftCopyrightResponse


async def add_sc(db: AsyncSession, sc: SoftCopyrightDB) -> SoftCopyrightDB:
    sc.created_time = utc_now()
    db.add(sc)
    await db.commit()
    await db.refresh(sc)
    return sc

async def get_sc_by_id(db: AsyncSession, sc_id: str) -> Optional[SoftCopyrightDB]:
    result = await db.execute(select(SoftCopyrightDB).filter(SoftCopyrightDB.id == sc_id))
    return result.scalars().first()

async def update_sc(db: AsyncSession, sc_id: str, soft_copyright_up: dict) -> SoftCopyrightDB | None:
    """
    更新软著信息
    """
    sc_info = await get_sc_by_id(db, sc_id)
    if sc_info:
        # 更新字段
        for key, value in soft_copyright_up.items():
            if hasattr(sc_info, key):
                setattr(sc_info, key, value)
        await db.commit()
        await db.refresh(sc_info)
        return sc_info
    return None


async def get_all_sc(db: AsyncSession, page_num: int, page_size: int) -> List[SoftCopyrightResponse] | None:
    """
    分页查看所有的软著信息
    :param db:
    :param page_num:
    :param page_size:
    :return:
    """
    # 参数校验
    if page_num < 1 or page_size < 1:
        raise ValueError("page_num and page_size must be positive integers")

    # 限制页面大小防止性能问题
    MAX_PAGE_SIZE = 1000
    if page_size > MAX_PAGE_SIZE:
        raise ValueError(f"page_size cannot exceed {MAX_PAGE_SIZE}")

    try:
        offset_value = (page_num - 1) * page_size
        # 确保offset为非负值
        offset_value = max(0, offset_value)

        result = await db.execute(
            select(SoftCopyrightDB)
            .order_by(SoftCopyrightDB.created_time.desc())
            .offset(offset_value)
            .limit(page_size)
        )
        db_objects =result.scalars().all()
        return [SoftCopyrightResponse.model_validate(obj) for obj in db_objects]
    except Exception as e:
        # 记录日志或重新抛出异常
        raise Exception(f"Database query failed: {str(e)}")
